package com.ruoyi.framework.annotation;


import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;

/**
 * 国密SM4加密工具增强版
 * 支持字符串和字节数组的加密/解密
 */
public final class SM4EncryptUtil {
    private static final String ALGORITHM_NAME = "SM4";
    private static final String ALGORITHM_CBC = "SM4/CBC/PKCS7Padding";
    private static final String DEFAULT_KEY = "abcde0123456789ffedcba9876543210";
    private static final String DEFAULT_IV = "fedcba987567894abcdef65432100123";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    // ------------------- 字节数组加密 -------------------
    public static byte[] encryptBytes(byte[] input) throws Exception {
        return encryptBytes(input, DEFAULT_KEY, DEFAULT_IV);
    }

    public static byte[] encryptBytes(byte[] input, String hexKey, String hexIv) throws Exception {
        validateHexParams(hexKey, hexIv);
        Cipher cipher = initCipher(hexKey, hexIv, Cipher.ENCRYPT_MODE);
        return cipher.doFinal(input);
    }

    // ------------------- 字符串加密 -------------------
    public static String encrypt(String plainText) throws Exception {
        return encrypt(plainText, DEFAULT_KEY, DEFAULT_IV);
    }

    public static String encrypt(String plainText, String hexKey, String hexIv) throws Exception {
        byte[] encrypted = encryptBytes(plainText.getBytes(StandardCharsets.UTF_8), hexKey, hexIv);
        return Hex.toHexString(encrypted);
    }

    // ------------------- 解密方法 -------------------
    public static String decrypt(String cipherText) throws Exception {
        byte[] decrypted = decryptBytes(Hex.decode(cipherText), DEFAULT_KEY, DEFAULT_IV);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    public static byte[] decryptBytes(byte[] input) throws Exception {
        return decryptBytes(input, DEFAULT_KEY, DEFAULT_IV);
    }

    public static byte[] decryptBytes(byte[] input, String hexKey, String hexIv) throws Exception {
        validateHexParams(hexKey, hexIv);
        Cipher cipher = initCipher(hexKey, hexIv, Cipher.DECRYPT_MODE);
        return cipher.doFinal(input);
    }

    // ------------------- 私有方法 -------------------
    private static Cipher initCipher(String hexKey, String hexIv, int mode) throws Exception {
        byte[] keyBytes = Hex.decode(hexKey);
        byte[] ivBytes = Hex.decode(hexIv);

        Cipher cipher = Cipher.getInstance(ALGORITHM_CBC, "BC");
        cipher.init(mode,
                new SecretKeySpec(keyBytes, ALGORITHM_NAME),
                new IvParameterSpec(ivBytes));
        return cipher;
    }

    private static void validateHexParams(String hexKey, String hexIv) {
        if (hexKey == null || hexKey.length() != 32 || !hexKey.matches("^[0-9a-fA-F]+$")) {
            throw new IllegalArgumentException("Invalid SM4 key format");
        }
        if (hexIv == null || hexIv.length() != 32 || !hexIv.matches("^[0-9a-fA-F]+$")) {
            throw new IllegalArgumentException("Invalid SM4 IV format");
        }
    }

    private SM4EncryptUtil() {}
}
